<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="umsroot.css">
<TITLE>
Communication via Streams
</TITLE>
</HEAD>
<BODY >
<A HREF="umsroot058.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="umsroot057.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot060.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc143">10.2</A>&nbsp;&nbsp;Communication via Streams</H2><UL>
<LI><A HREF="umsroot059.html#toc86">Character I/O</A>
<LI><A HREF="umsroot059.html#toc87">Token I/O</A>
<LI><A HREF="umsroot059.html#toc88">Term I/O</A>
<LI><A HREF="umsroot059.html#toc89">Newlines</A>
<LI><A HREF="umsroot059.html#toc90">General Parsing and Text Generation</A>
<LI><A HREF="umsroot059.html#toc91">Flushing</A>
<LI><A HREF="umsroot059.html#toc92">Prompting</A>
<LI><A HREF="umsroot059.html#toc93">Positioning</A>
</UL>

The contents of a stream may be interpreted in one of the
three basic ways.
The first one is to
consider it as a sequence of characters, so that the basic unit to
be read or written is a character. The second one interprets
the stream as a sequence of tokens, thus providing an interface
to the Prolog lexical analyzer and the third one is to consider a stream as
a sequence of Prolog terms.<BR>
<BR>
<A NAME="toc86"></A>
<H3 CLASS="subsection"><A NAME="htoc144">10.2.1</A>&nbsp;&nbsp;Character I/O</H3>
The <A HREF="../bips/kernel/iochar/get-1.html"><B>get/1, 2</B></A><A NAME="@default549"></A> and <A HREF="../bips/kernel/iochar/put-1.html"><B>put/1, 2</B></A><A NAME="@default550"></A>
<A NAME="@default551"></A>
<A NAME="@default552"></A>
<A NAME="@default553"></A>
<A NAME="@default554"></A>
predicates corresponds to the first way
of looking at streams. The call<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
get(Char)</PRE></BLOCKQUOTE> takes the next character
from
the current input stream and matches it as a single character with Char.
Note that a character in ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> is represented as an integer corresponding
to the ASCII code of the character.
If the end of file has been reached then an exception is raised.
The call<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
put(Char)</PRE></BLOCKQUOTE> puts the char Char on to the current output
stream.
The predicates
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
get(Stream, Char)</PRE></BLOCKQUOTE> and
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
put(Stream, Char)</PRE></BLOCKQUOTE> work similarly on the specified stream.<BR>
<BR>
The input and output is normally buffered by ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>.
To make I/O in <I>raw mode</I>, without buffering, the predicates
<A HREF="../bips/kernel/iochar/tyi-1.html"><B>tyi/1, 2</B></A><A NAME="@default555"></A> and <A HREF="../bips/kernel/iochar/tyo-1.html"><B>tyo/1, 2</B></A><A NAME="@default556"></A> are provided.
<A NAME="@default557"></A>
<A NAME="@default558"></A>
<A NAME="@default559"></A>
<A NAME="@default560"></A><BR>
<BR>
<A NAME="toc87"></A>
<H3 CLASS="subsection"><A NAME="htoc145">10.2.2</A>&nbsp;&nbsp;Token I/O</H3>
<A NAME="@default561"></A>
The predicates
<A HREF="../bips/kernel/iochar/read_token-2.html"><B>read_token/2</B></A><A NAME="@default562"></A> and
<A HREF="../bips/kernel/iochar/read_token-3.html"><B>read_token/3</B></A><A NAME="@default563"></A>
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
read_token(Token, Class)
read_token(Stream, Token, Class)
</PRE></BLOCKQUOTE>
represent the second way of interpreting stream contents.
They read the next token from the current
input stream, unify it with <I>Token</I>,
and its token class is unified with <I>Class</I>.
A token is either a sequence of characters with the same or compatible
<A NAME="@default564"></A>
character class, e.g. ab_1A, then it is a Prolog constant
or variable, or a single character, e.g. ')'.
<A NAME="@default565"></A>
The token class represents the type of the token and
its special meaning, e.g. <TT>fullstop</TT>, <TT>comma</TT>, <TT>open_par</TT>, etc.
The exact definition of character classes and tokens can be found in
appendices <A HREF="umsroot141.html#charclass">A.2.1</A> and <A HREF="umsroot141.html#tokendef">A.2.3</A>, respectively.<BR>
<BR>
A further, very flexible possibility to read a sequence of
characters is provided by the built-ins
<A HREF="../bips/kernel/iochar/read_string-3.html"><B>read_string/3</B></A><A NAME="@default566"></A> and
<A HREF="../bips/kernel/iochar/read_string-4.html"><B>read_string/4</B></A><A NAME="@default567"></A>
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
read_string(Delimiters, Length, String)
read_string(Stream, Delimiters, Length, String)
</PRE></BLOCKQUOTE>
Here, the input is read up to a specified delimiter or up to a specified
length, and returned as an ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> string.<BR>
<BR>
In particular, one line of input can be read as follows:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
read_line(Stream, String) :-
    read_string(Stream, end_of_line, _Length, String).
</PRE></BLOCKQUOTE>
Once a string has been read, string manipulation predicates like
<A HREF="../bips/kernel/stratom/split_string-4.html"><B>split_string/4</B></A><A NAME="@default568"></A>
can be used to break it up into smaller components.<BR>
<BR>
<A NAME="toc88"></A>
<H3 CLASS="subsection"><A NAME="htoc146">10.2.3</A>&nbsp;&nbsp;Term I/O</H3>
The <A HREF="../bips/kernel/ioterm/read-1.html"><B>read/1, 2</B></A><A NAME="@default569"></A> and <A HREF="../bips/kernel/ioterm/write-1.html"><B>write/1, 2</B></A><A NAME="@default570"></A> predicates correspond to
<A NAME="@default571"></A>
<A NAME="@default572"></A>
<A NAME="@default573"></A>
<A NAME="@default574"></A>
the third way of looking at streams.
For input, the goal <BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
read(Term)</PRE></BLOCKQUOTE> reads the next ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> term from the current input
stream and unifies it with <I>Term</I>. The input term must be followed by a
full stop, that is, a '.' character followed by a layout
character (tab, space or newline) or by the end of file.
The exact definition of the term syntax can be found in appendix
<A HREF="umsroot139.html#chapsyntax">A</A>.<BR>
<BR>
If end of file has been reached then
an exception is raised, the default handler causes the atom
<I>end_of_file</I> to be returned.
A term may be read from a stream other than the current input stream by
the call <BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
read(Stream, Term)</PRE></BLOCKQUOTE> which reads the term from the
named stream.<BR>
<BR>
For additional information about other options for reading terms,
in particular for how to get variable names, refer to
<A HREF="../bips/kernel/ioterm/readvar-3.html"><B>readvar/3</B></A><A NAME="@default575"></A>,
<A HREF="../bips/kernel/ioterm/read_term-2.html"><B>read_term/2</B></A><A NAME="@default576"></A> and
<A HREF="../bips/kernel/ioterm/read_term-3.html"><B>read_term/3</B></A><A NAME="@default577"></A>.
For reading and processing complete ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> source code files, use the
<A HREF="../bips/lib/source_processor/index.html"><B>library(source_processor)</B></A><A NAME="@default578"></A>.<BR>
<BR>
For output, the goal <BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
write(Term)</PRE></BLOCKQUOTE> writes <I>Term</I> to the current output stream.
<A NAME="@default579"></A>
<A NAME="@default580"></A>
This is done by taking the current operator declarations into account. Output
produced by the <A HREF="../bips/kernel/ioterm/write-1.html"><B>write/1, 2</B></A><A NAME="@default581"></A> predicate is not (necessarily) in
a form suitable for subsequent input to a Prolog program using the <A HREF="../bips/kernel/ioterm/read-1.html"><B>read/1</B></A><A NAME="@default582"></A>
predicate, for this purpose <A HREF="../bips/kernel/ioterm/writeq-1.html"><B>writeq/1, 2</B></A><A NAME="@default583"></A> is to be used.
<A NAME="@default584"></A>
<A NAME="@default585"></A>
The goal <BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
write(Stream, Term)</PRE></BLOCKQUOTE> writes <I>Term</I> to the
named output stream.
For more details about how to output terms in different formats, see
section <A HREF="umsroot061.html#secoutputformats">10.4</A>.<BR>
<BR>
When the flag <TT>variable_names</TT> is switched off,
<A NAME="@default586"></A>
the output predicates are not able to write free variables
in their source form, i.e. with the correct variable names.
Then the variables are output in the form
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
_N</PRE></BLOCKQUOTE>
where <TT>N</TT> is a number which identifies the variable (but note that these
numbers may change on garbage collection and can therefore not be used to
identify the variable in a more permanent way).
Occasionally the number will be prefixed with the lower-case letter <TT>l</TT>,
indicating that the variable is in a short-lived memory area called the
local stack (see <A HREF="umsroot121.html#chapmemory">19</A>).
<A NAME="@default587"></A><BR>
<BR>
<A NAME="toc89"></A>
<H3 CLASS="subsection"><A NAME="htoc147">10.2.4</A>&nbsp;&nbsp;Newlines</H3>

Newlines should be output using either
<A HREF="../bips/kernel/iochar/nl-0.html"><B>nl/0</B></A><A NAME="@default588"></A>,
<A HREF="../bips/kernel/iochar/nl-1.html"><B>nl/1</B></A><A NAME="@default589"></A>,
<A HREF="../bips/kernel/ioterm/writeln-1.html"><B>writeln/1</B></A><A NAME="@default590"></A>,
<A HREF="../bips/kernel/ioterm/writeln-2.html"><B>writeln/2</B></A><A NAME="@default591"></A>,
or using the "%n" format with
<A HREF="../bips/kernel/ioterm/printf-2.html"><B>printf/2</B></A><A NAME="@default592"></A>,
<A HREF="../bips/kernel/ioterm/printf-3.html"><B>printf/3</B></A><A NAME="@default593"></A>.
All those will produce a LF or CRLF sequence, depending on the
stream property settings (see
<A HREF="../bips/kernel/iostream/set_stream_property-3.html"><B>set_stream_property/3</B></A><A NAME="@default594"></A>).<BR>
<BR>
<A NAME="toc90"></A>
<H3 CLASS="subsection"><A NAME="htoc148">10.2.5</A>&nbsp;&nbsp;General Parsing and Text Generation</H3>

Reading and writing of I/O formats that cannot be handled by the methods
discussed above are probably best done using Definite Clause Grammar
(DCG) rules. See chapter <A HREF="umsroot069.html#dcg">12.3</A> for details.<BR>
<BR>
<A NAME="toc91"></A>
<H3 CLASS="subsection"><A NAME="htoc149">10.2.6</A>&nbsp;&nbsp;Flushing</H3>
On most devices, output is buffered, i.e. any output does not appear
<A NAME="@default595"></A>
immediately on the file, pipe or socket, but goes into a buffer first.
To make sure the data is actually written to the device, the stream
usually has to be flushed using
<A HREF="../bips/kernel/iostream/flush-1.html"><B>flush/1</B></A><A NAME="@default596"></A>.
If this is forgotten, the receiving end of a pipe or socket may hang
in a blocking read operation.<BR>
<BR>
It is possible to configure a stream such that it is automatically
flushed at every line end (see 
<A HREF="../bips/kernel/iostream/set_stream_property-3.html"><B>set_stream_property/3</B></A><A NAME="@default597"></A>).<BR>
<BR>
<A NAME="toc92"></A>
<H3 CLASS="subsection"><A NAME="htoc150">10.2.7</A>&nbsp;&nbsp;Prompting</H3>
Input streams on terminals can be configured to print a prompt
whenever input is required, see 
<A HREF="../bips/kernel/iostream/set_stream_property-3.html"><B>set_stream_property/3</B></A><A NAME="@default598"></A>.<BR>
<BR>
<A NAME="toc93"></A>
<H3 CLASS="subsection"><A NAME="htoc151">10.2.8</A>&nbsp;&nbsp;Positioning</H3>
Streams that are opened on files or strings can be positioned,
ie. the read/write position can be moved forward or backwards.
This is not possible on pipes, sockets, queues and terminals.<BR>
<BR>
To specify a position in the file
to write to or read from, the predicate <A HREF="../bips/kernel/iostream/seek-2.html"><B>seek/2</B></A><A NAME="@default599"></A> is provided. The
<A NAME="@default600"></A>
call <BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
seek(Stream, Pointer)</PRE></BLOCKQUOTE> moves the current position in the
file (the 'file pointer') to the offset <I>Pointer</I> (a number specifying
the length in bytes) from
the start of the file.
If <I>Pointer</I> is the atom <I>end_of_file</I> the
current position is moved to the end of the file.
Hence a file could be open in <TT>append</TT> mode using
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
open(File, update, Stream), seek(Stream, end_of_file)</PRE></BLOCKQUOTE>
The current position in a file may be found by the predicate <A HREF="../bips/kernel/iostream/at-2.html"><B>at/2</B></A><A NAME="@default601"></A>.
<A NAME="@default602"></A>
The call <BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
at(Stream, Pointer)</PRE></BLOCKQUOTE> unifies <I>Pointer</I> with the current
position in the file.
The predicate
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
at_eof(Stream)</PRE></BLOCKQUOTE>
succeeds if the current position in the given stream
is at the file end.<BR>
<BR>
<HR>
<A HREF="umsroot058.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="umsroot057.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot060.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
